#include <input_manager.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define BUFFER_LEN 20
static pthread_mutex_t g_tMutex  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tConVer = PTHREAD_COND_INITIALIZER;
PInputDevice gp_InputDevice = NULL;
static int g_iwrite = 0;
static int g_iread  = 0;
static InputEvent g_apInputEvents[BUFFER_LEN];

static int InputBufferFull(void)
{
	return (g_iread == ((g_iwrite + 1)%BUFFER_LEN));
}

static int InputBufferEmpty(void)
{
	return (g_iread == g_iwrite);
}

static void Put_InputEvent_toBuffer(PInputEvent ptInputEvent)
{
	if(!InputBufferFull())
	{
		g_apInputEvents[g_iwrite] = *ptInputEvent;
		g_iwrite = ( g_iwrite + 1 ) % BUFFER_LEN;
	}
}

static int Get_InputEvent_FromBuffer(PInputEvent ptInputEvent)
{
	if(!InputBufferEmpty())
	{
		*ptInputEvent = g_apInputEvents[g_iread];
		g_iread = ( g_iread + 1 ) % BUFFER_LEN;
		return 1;
	}
	else return 0;
}

void Register_InputDevice(PInputDevice pInputDevice)
{
	pInputDevice->pNext = gp_InputDevice;
	gp_InputDevice = pInputDevice;
}

void InputDev_Register()
{
	/************外部函数声明加上extern************/
	/* TouchScreen  */
	extern void TouchScreenDev_Register(void);
	TouchScreenDev_Register();
	/* Net  */
	extern void NetInputDev_Register(void);
	NetInputDev_Register();
}

void *InitDev_Pthread(void * pramer)
{
	PInputDevice ptInputDev = (PInputDevice)pramer;
	InputEvent	tEvent;
	int ret;
	while(1)
	{
		ret = ptInputDev->GetInputEvent(&tEvent);
		if(!ret)
		{	
			pthread_mutex_lock(&g_tMutex);
			Put_InputEvent_toBuffer(&tEvent);
			pthread_cond_signal(&g_tConVer);
			pthread_mutex_unlock(&g_tMutex);
		}
	}
}

void InputDevice_Init(void)
{
	pthread_t tid;
	int ret;
	PInputDevice pt_Temp = gp_InputDevice;

	
	while(pt_Temp)
	{
		ret = pt_Temp->DeviceInit();
		if(!ret)
		{
			/* pthread create */
			ret = pthread_create(&tid , NULL , InitDev_Pthread , (void *)pt_Temp);
		}

		pt_Temp = pt_Temp->pNext;	
	}
}

int GetInputEvent(PInputEvent ptInputEvent)
{
	int ret;
	InputEvent tEvent;
	pthread_mutex_lock(&g_tMutex);
	if(Get_InputEvent_FromBuffer (&tEvent))
	{
		ret = 1;
		*ptInputEvent = tEvent;
		pthread_mutex_unlock(&g_tMutex);
	}
	else
	{
		pthread_cond_wait(&g_tConVer ,&g_tMutex);
		if(Get_InputEvent_FromBuffer (&tEvent))
		{
			*ptInputEvent = tEvent;
			ret = 1;
		}
		else
			ret = 0;
		pthread_mutex_unlock(&g_tMutex);
	}
	return ret;
}

